home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ddj0897.zip
/
ISERVER.ZIP
/
MFCISAPI.ZIP
/
ISERVER.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-09
|
9KB
|
314 lines
// IServer.cpp : implementation file
//
#include "stdafx.h"
#include "cbisapi.h"
#include "IServer.h"
#include <malloc.h>
#include <afxconv.h> // BSTR conversions
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIsapiServer
IMPLEMENT_DYNCREATE(CIsapiServer, CCmdTarget)
CIsapiServer::CIsapiServer()
{
EnableAutomation();
}
CIsapiServer::~CIsapiServer()
{
}
void CIsapiServer::OnFinalRelease()
{
CCmdTarget::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CIsapiServer, CCmdTarget)
//{{AFX_MSG_MAP(CIsapiServer)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CIsapiServer, CCmdTarget)
//{{AFX_DISPATCH_MAP(CIsapiServer)
DISP_PROPERTY(CIsapiServer, "RetVal", m_retVal, VT_I4)
DISP_PROPERTY(CIsapiServer, "StatCode", m_statCode, VT_I4)
DISP_PROPERTY_EX(CIsapiServer, "Method", GetMethod, SetNotSupported, VT_BSTR)
DISP_PROPERTY_EX(CIsapiServer, "QueryString", GetQueryString, SetNotSupported, VT_BSTR)
DISP_PROPERTY_EX(CIsapiServer, "PathInfo", GetPathInfo, SetNotSupported, VT_BSTR)
DISP_PROPERTY_EX(CIsapiServer, "PathTranslated", GetPathTranslated, SetNotSupported, VT_BSTR)
DISP_PROPERTY_EX(CIsapiServer, "ContentLength", GetContentLength, SetNotSupported, VT_I4)
DISP_PROPERTY_EX(CIsapiServer, "Content", GetContent, SetNotSupported, VT_BSTR)
DISP_PROPERTY_EX(CIsapiServer, "ContentType", GetContentType, SetNotSupported, VT_BSTR)
DISP_FUNCTION(CIsapiServer, "Write", Write, VT_BOOL, VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "ServerVariable", ServerVariable, VT_BOOL, VTS_VARIANT VTS_PVARIANT)
DISP_FUNCTION(CIsapiServer, "WriteLine", WriteLine, VT_BOOL, VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "WriteByte", WriteByte, VT_BOOL, VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "ServerDoneSession", ServerDoneSession, VT_BOOL, VTS_NONE)
DISP_FUNCTION(CIsapiServer, "Redirect", Redirect, VT_BOOL, VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "SendURL", SendURL, VT_BOOL, VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "SendHeaders", SendHeaders, VT_BOOL, VTS_VARIANT VTS_VARIANT)
DISP_FUNCTION(CIsapiServer, "MapURL2Path", MapURL2Path, VT_BOOL, VTS_PVARIANT)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_IIsapiServer to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// Not really used in any meaningful way, but the wiz puts it here
// {A3B7D305-647C-11D0-A7B2-444553540000}
static const IID IID_IIsapiServer =
{ 0xa3b7d305, 0x647c, 0x11d0, { 0xa7, 0xb2, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
BEGIN_INTERFACE_MAP(CIsapiServer, CCmdTarget)
INTERFACE_PART(CIsapiServer, IID_IIsapiServer, Dispatch)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIsapiServer message handlers
// Write to client
BOOL CIsapiServer::Write(const VARIANT FAR& idata)
{
COleVariant data=idata;
USES_CONVERSION;
data.ChangeType(VT_BSTR); // Force to BSTR
if (data.vt!=VT_BSTR)
return FALSE;
char *s=W2A(data.bstrVal); // switch to ANSI
DWORD siz=strlen(s);
return ecb->WriteClient(ecb->ConnID,s,&siz,0); // out!
}
// This fetches a Server Variable into a VARIANT
// Be careful. Since the second argument is a variant
// by reference, the formal argument must really be
// a variant. In other words, NO:
// dim x as string
// server.ServerVariable "SCRIPT_NAME",x
// YES:
// dim x as variant
// server.ServerVariable "SCRIPT_NAME",x
// Probably should have been a function returning VARIANT, but then
// again...
BOOL CIsapiServer::ServerVariable(const VARIANT FAR& Variable,
VARIANT FAR* Result)
{
COleVariant var;
var=Variable;
var.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
USES_CONVERSION;
char *v=W2A(var.bstrVal);
CString res;
DWORD siz=1024;
BOOL rv;
rv=ecb->GetServerVariable(ecb->ConnID,v,
(char *)res.GetBufferSetLength(siz),&siz);
res.ReleaseBuffer(siz-1);
VariantClear(Result);
Result->vt=VT_BSTR;
Result->bstrVal=res.AllocSysString();
return rv;
}
// R/O Property -- these all look the same
BSTR CIsapiServer::GetMethod()
{
CString strResult=ecb->lpszMethod;
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// Another R/O Property
BSTR CIsapiServer::GetQueryString()
{
CString strResult=ecb->lpszQueryString;
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// R/O Property
BSTR CIsapiServer::GetPathInfo()
{
CString strResult=ecb->lpszPathInfo;
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// R/O Property
BSTR CIsapiServer::GetPathTranslated()
{
CString strResult=ecb->lpszPathTranslated;
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// R/O Property
long CIsapiServer::GetContentLength()
{
return ecb->cbTotalBytes;
}
// R/O Property with a twist
// Apparently sometimes the server calls the
// extension without having all the content
// data (does this really happen?)
// This function reads it all so it is available
// BTW, the docs say that if the count is
// 0xFFFFFFFF then MORE than 4G of data
// is forthcoming and you should call ReadClient
// until it is empty
// NEWS BULLETIN: If you expect 4G or more in
// a request, don't use these functions!
BSTR CIsapiServer::GetContent()
{
CString strResult;
char *p=strResult.GetBufferSetLength(ecb->cbTotalBytes);
// put available bytes in CString
memcpy(p,ecb->lpbData,ecb->cbAvailable);
// Read excess
if (ecb->cbAvailable!=ecb->cbTotalBytes)
{
DWORD siz=ecb->cbTotalBytes-ecb->cbAvailable;
ecb->ReadClient(ecb->ConnID,p+ecb->cbAvailable,&siz);
}
strResult.ReleaseBuffer(ecb->cbTotalBytes);
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// Another R/O
BSTR CIsapiServer::GetContentType()
{
CString strResult=ecb->lpszContentType;
BSTR rv;
rv=strResult.AllocSysString();
return rv;
}
// Simple Method to write a line
// Note that HTML doesn't care one
// whit about the \r\n -- it just
// makes the HTML source nicer
// Use <P> or <BR> to get a newline in HTML
BOOL CIsapiServer::WriteLine(const VARIANT FAR& idata)
{
BOOL rv=Write(idata);
DWORD siz=2;
if (rv) rv=ecb->WriteClient(ecb->ConnID,"\r\n",&siz,0);
return rv;
}
// Write a byte out
BOOL CIsapiServer::WriteByte(const VARIANT FAR& byte)
{
COleVariant num=byte;
num.ChangeType(VT_UI1);
if (num.vt!=VT_UI1)
return FALSE;
char s=num.bVal;
DWORD siz=1;
return ecb->WriteClient(ecb->ConnID,&s,&siz,0);
}
// Wrap ServerSupportFunction Done with Session
BOOL CIsapiServer::ServerDoneSession()
{
return ecb->ServerSupportFunction(ecb->ConnID,
HSE_REQ_DONE_WITH_SESSION,NULL,NULL,NULL);
}
// Redirect to another URL (wrap ServerSupportFunction)
BOOL CIsapiServer::Redirect(const VARIANT FAR& url)
{
COleVariant var;
var=url;
var.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
USES_CONVERSION;
char *v=W2A(var.bstrVal);
DWORD siz=strlen(v);
return ecb->ServerSupportFunction(ecb->ConnID,
HSE_REQ_SEND_URL_REDIRECT_RESP,v,&siz,NULL);
}
// Send alternate URL (wrap ServerSupportFunction)
BOOL CIsapiServer::SendURL(const VARIANT FAR& url)
{
COleVariant var;
var=url;
var.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
USES_CONVERSION;
char *v=W2A(var.bstrVal);
DWORD siz=strlen(v);
return ecb->ServerSupportFunction(ecb->ConnID,
HSE_REQ_SEND_URL,v,&siz,NULL);
}
// Send headers (wrap ServerSupport Function)
BOOL CIsapiServer::SendHeaders(const VARIANT FAR& Status,
const VARIANT FAR& Headers)
{
COleVariant var,var2;
var=Status;
var2=Headers;
var.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
var2.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
USES_CONVERSION;
char *status=W2A(var.bstrVal);
char *hdr=W2A(var.bstrVal);
return ecb->ServerSupportFunction(ecb->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,status,NULL,(DWORD *)hdr);
}
// Map Virtual Path to Real Path (wrap ServerSupportFunction)
BOOL CIsapiServer::MapURL2Path(VARIANT FAR* urlpath)
{
BOOL rv;
COleVariant var,var2;
var=urlpath;
var.ChangeType(VT_BSTR);
if (var.vt!=VT_BSTR) return FALSE;
USES_CONVERSION;
char *varin=W2A(var.bstrVal);
DWORD siz=1024;
CString url(varin);
rv=ecb->ServerSupportFunction(ecb->ConnID,
HSE_REQ_MAP_URL_TO_PATH,
url.GetBufferSetLength(siz),&siz,NULL);
url.ReleaseBuffer(siz-1);
// set up return value
VariantClear(urlpath);
urlpath->vt=VT_BSTR;
urlpath->bstrVal=url.AllocSysString();
return rv;
}